﻿namespace Wolfpack.Contrib.Checks.EventLogParser
{
    using System;
    using System.Collections.Generic;
    using System.Diagnostics;
    using System.IO;
    using Wolfpack.Core;
    using Wolfpack.Core.Interfaces;
    using Wolfpack.Core.Interfaces.Entities;

    /// <summary>
    /// The Plugin.
    /// </summary>
    public class EventLogCheck : IHealthCheckPlugin
    {
        #region Readonly Fields
        /// <summary>
        /// The CheckId of an error.
        /// </summary>
        protected readonly String ErrorCheckId;

        /// <summary>
        /// The expression to search for in the message portion of the Eventlog entry.
        /// </summary>
        protected readonly String DefinedSearchExpression;

        /// <summary>
        /// The max number of entries to iterate through.
        /// </summary>
        protected readonly int DefinedMaxLogEntries;

        /// <summary>
        /// The eventlog entry source to search for.
        /// </summary>
        protected readonly String DefinedSource;

        /// <summary>
        /// The eventlog type to search for.
        /// </summary>
        protected readonly String DefinedEntryType;

        /// <summary>
        /// The eventlog name to search for.
        /// </summary>
        protected readonly String DefinedEventLogName;

        /// <summary>
        /// The maximum number of seconds to search back to.
        /// </summary>
        protected readonly int DefinedMaxSecondsToRead;

        /// <summary>
        /// The number of failures to match before reporting a health check failure.
        /// </summary>
        protected readonly int DefinedNumberOfConsecutiveFailures;

        /// <summary>
        /// The number of matches before reporting a health check failure.
        /// </summary>
        protected readonly int DefinedNumberOfEventLogMatches;

        protected readonly string CheckId;
        #endregion

        #region Fields and Properties
        /// <summary>
        /// Gets or sets the total number of consequtive Health Check failures.
        /// </summary>
        private int currentConsecutiveFailures;
        protected int CurrentConsecutiveFailures
        {
            get { return currentConsecutiveFailures; }
            set { currentConsecutiveFailures = value; }
        }

        /// <summary>
        /// Gets or sets the PluginDescriptor.
        /// </summary>
        private PluginDescriptor identity;
        public PluginDescriptor Identity
        {
            get { return identity; }
            set { identity = value; }
        }

        private int lastTotalLogEntries;

        /// <summary>
        /// Gets or sets the total number of log entries of our last check. 
        /// This is used to keep track of the total eventlog entrie
        /// </summary>
        protected int LastTotalLogEntries
        {
            get { return lastTotalLogEntries; }
            set { lastTotalLogEntries = value; }
        }

        /// <summary>
        /// Gets or sets Status.
        /// </summary>
        private Status status;
        public Status Status
        {
            get { return status; }
            set { status = value; }
        }

        #endregion

        #region Constructor
        /// <summary>
        /// Initializes a new instance of the <see cref="EventLogCheck"/> class.
        /// </summary>
        /// <param name="config">
        /// The config file.
        /// </param>pp
        public EventLogCheck(EventLogCheckConfig config)
        {
            // private PluginDescriptor identity;
            identity = new PluginDescriptor
            {
                Description = "Provides Information about the Windows Eventlog",
                Name = config.FriendlyId,
                TypeId = new Guid("FD8C7E63-5CF7-43FE-81BD-3C414914C634")
            };

            // protected readonly string CheckId;
            CheckId = config.FriendlyId;

            // private int currentFailures;
            currentConsecutiveFailures = 0;

            #region DefinedMaxLogEntries
            // protected readonly int DefinedMaxLogEntries;
            if (String.IsNullOrEmpty(config.MaxLogEntries))
            {
                DefinedMaxLogEntries = 200;
            }
            else
            {
                DefinedMaxLogEntries = int.Parse(config.MaxLogEntries);
            }
            #endregion

            #region DefinedNumberOfConsecutiveFailures
            // protected readonly int DefinedNumberOfFailures;
            if (String.IsNullOrEmpty(config.NumberOfFailures))
            {
                DefinedNumberOfConsecutiveFailures = 1;
            }
            else
            {
                DefinedNumberOfConsecutiveFailures = int.Parse(config.NumberOfFailures);
            }
            #endregion

            #region DefinedNumberOfEventLogMatches
            // protected readonly int DefinedNumberOfMatches;
            if (String.IsNullOrEmpty(config.NumberOfMatches))
            {
                DefinedNumberOfEventLogMatches = 1;
            }
            else
            {
                DefinedNumberOfEventLogMatches = int.Parse(config.NumberOfMatches);
            }
            #endregion

            #region DefinedMaxSecondsToRead
            // protected readonly int DefinedMaxSecondsToRead;
            if (String.IsNullOrEmpty(config.MaxSecondsToRead))
            {
                DefinedMaxSecondsToRead = 86400;
            }
            else
            {
                DefinedMaxSecondsToRead = int.Parse(config.MaxSecondsToRead);
            }
            #endregion

            // protected readonly String DefinedEventLogName;
            DefinedEventLogName = config.EventLogName;

            // protected readonly String DefinedSearchExpression;
            DefinedSearchExpression = config.SearchExpression;

            // protected readonly String DefinedSource;
            DefinedSource = config.Source;

            // protected readonly String DefinedEntryType;
            DefinedEntryType = config.EntryType;

            // protected readonly String ErrorCheckId;
            ErrorCheckId = "WP" + this.GetType().Name + "Error";

            // private int lastTotalLogEntries;
            lastTotalLogEntries = 0;
        }

        #endregion

        /// <summary>
        /// Performs a one-time initialization. This is done after the constructor.
        /// </summary>
        public void Initialise()
        {
        }

        /// <summary>
        /// This runs when the plugin is called.
        /// </summary>
        public void Execute()
        {
            FileInfo filename = new FileInfo(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Working", CheckId + ".txt"));

            DateTime startTime = DateTime.Now;

            Logger.Debug("'{0}': Starting the eventlog parser at: '{1}'",
                CheckId,
                startTime.ToString());

            DateTime lastStartTime;

            #region Check for working file and write start time.
            try
            {
                if (filename.Exists)
                {
                    using (StreamReader reader = new StreamReader(File.OpenRead(filename.ToString())))
                    {
                        lastStartTime = Convert.ToDateTime(reader.ReadLine());
                    }

                    Logger.Debug("'{0}': Working file exists. Last start time was: '{1}'.",
                        CheckId,
                        lastStartTime.ToString());

                    SetStartTime(CheckId, filename, startTime);

                    if (!IsUnderMaxSeconds(CheckId, ErrorCheckId, lastStartTime, DefinedMaxSecondsToRead))
                    {
                        string message = String.Format("Our Config file has a date/time stamp that is over our max seconds to read. Last time stamp: '{0}'. MaxSeconds to read: '{1}'. Current time stamp. '{2}'.",
                            lastStartTime.ToString(),
                            DefinedMaxSecondsToRead.ToString(),
                            DateTime.Now.ToString());

                        Logger.Debug(message);

                        Publish(ErrorCheckId,
                            message,
                            true,
                            DefinedEventLogName,
                            LastTotalLogEntries,
                            DefinedSource,
                            CheckId,
                            DefinedEntryType,
                            CurrentConsecutiveFailures,
                            DefinedMaxLogEntries,
                            DefinedMaxSecondsToRead);

                        CurrentConsecutiveFailures = 0;

                        Finish(CheckId, "Resetting current number of consecutive health check failures, setting the start time, and exiting.");

                        return;
                    }
                }
                else
                {
                    Finish(CheckId, string.Format("Working file does not exist.  Time written to file:'{0}'. Exiting.",
                        startTime.ToString()));

                    CurrentConsecutiveFailures = 0;

                    SetStartTime(CheckId, filename, startTime);

                    return;
                }

                if (String.IsNullOrEmpty(lastStartTime.ToString()))
                {
                    Finish(CheckId, String.Format("Working file is empty. Time written to file: '{0}'. Exiting.",
                        startTime.ToString()));

                    CurrentConsecutiveFailures = 0;

                    SetStartTime(CheckId, filename, startTime);

                    return;
                }
            }
            catch (Exception ex)
            {
                string message = String.Format("'{0}': Exception while reading last check time: '{1}'. Time written to file: '{2}'. Exiting.",
                    CheckId,
                    ex.InnerException.Message,
                    startTime.ToString());

                Publish(
                    ErrorCheckId,
                    message,
                    true,
                    DefinedEventLogName,
                    LastTotalLogEntries,
                    DefinedSource,
                    CheckId,
                    DefinedEntryType,
                    CurrentConsecutiveFailures,
                    DefinedMaxLogEntries,
                    DefinedMaxSecondsToRead);

                Finish(CheckId, message);

                CurrentConsecutiveFailures = 0;

                SetStartTime(CheckId, filename, startTime);

                return;
            }
            #endregion

            EventLog eventLog = default(EventLog);

            try
            {
                eventLog = new EventLog(DefinedEventLogName);

                // Assigning the count now as it may increase if a new record is added to the eventlog.
                int currentTotalLogEntries = eventLog.Entries.Count;

                if (HasRecords(CheckId, currentTotalLogEntries)
                        && HasNewEntries(CheckId, eventLog.Entries[currentTotalLogEntries - 1].TimeWritten, lastStartTime, currentTotalLogEntries, LastTotalLogEntries))
                {
                    // Keep count of the number of entries we have iterated through so we can see if we are over the max number of records.
                    int countOfEntries = 0;
                    int numberOfEventLogMatches = 0;

                    // start from the top and work down.
                    for (int i = currentTotalLogEntries - 1; i >= 0; i--)
                    {
                        Logger.Debug("'{0}': Checking eventlog number '{1}'", CheckId, i.ToString());

                        // Check only log entries that have a DateTime >= the last pull time.
                        if (IsGreaterThanLastStartTime(CheckId, eventLog.Entries[i].TimeWritten, lastStartTime)
                            && IsUnderMaxLogEntries(CheckId, countOfEntries))
                        {
                            countOfEntries++;

                            EventLogEntry entry = eventLog.Entries[i];

                            if (IsMatchOnType(CheckId, entry.EntryType.ToString())
                                && IsMatchOnSource(CheckId, entry.Source)
                                && IsMatchOnMessage(CheckId, entry.Message.ToLower(), DefinedSearchExpression.ToLower()))
                            {
                                if (IsEqualToOrOverNumberOfEventLogMatches(CheckId, ++numberOfEventLogMatches, DefinedNumberOfEventLogMatches))
                                {
                                    if (IsEqualToOrOverNumberOfConsecutiveFailures(CheckId, ++CurrentConsecutiveFailures, DefinedNumberOfConsecutiveFailures))
                                    {
                                        Publish(CheckId,
                                            "Match Found.",
                                            false,
                                            DefinedEventLogName,
                                            currentTotalLogEntries,
                                            DefinedSource,
                                            CheckId,
                                            DefinedEntryType,
                                            CurrentConsecutiveFailures,
                                            DefinedMaxLogEntries,
                                            DefinedMaxSecondsToRead);

                                        LastTotalLogEntries = currentTotalLogEntries;

                                        Finish(ref eventLog, CheckId, "Current ConsecutiveFailures are over the number of defined consecutive failures. Publishing.");

                                        return;
                                    }
                                    else
                                    {
                                        Finish(CheckId, String.Format("Number of matches condition met '{0}', but consecutive health check failures is only '{1}'.",
                                            numberOfEventLogMatches.ToString(),
                                            CurrentConsecutiveFailures.ToString()));

                                        LastTotalLogEntries = currentTotalLogEntries;

                                        return;
                                    }
                                }

                            }
                        }
                        // Not greater than last start time or over max entries.
                        else
                        {
                            string message = default(string);

                            // we have exceeded the number of eventlog entries defined in our config.
                            if (!IsUnderMaxLogEntries(CheckId, countOfEntries))
                            {
                                message = String.Format("Current count of entries examined '{0}' is greater than  Max log entries '{1}'.",
                                    countOfEntries.ToString(), DefinedMaxLogEntries.ToString());

                                Publish(ErrorCheckId,
                                message,
                                true,
                                DefinedEventLogName,
                                currentTotalLogEntries,
                                DefinedSource,
                                CheckId,
                                DefinedEntryType,
                                CurrentConsecutiveFailures,
                                DefinedMaxLogEntries,
                                DefinedMaxSecondsToRead);
                            }
                            else if (!IsGreaterThanLastStartTime(CheckId, eventLog.Entries[i].TimeWritten, lastStartTime))
                            {
                                message = String.Format("The last start time '{0}' is greater than the eventLogEntry write time '{1}'.",
                                        countOfEntries.ToString(), DefinedMaxLogEntries.ToString(), lastStartTime.ToString(), eventLog.Entries[i].TimeWritten.ToString());
                            }

                            Finish(ref eventLog,
                                CheckId,
                                message);

                            CurrentConsecutiveFailures = 0;

                            LastTotalLogEntries = currentTotalLogEntries;

                            return;
                        }
                    }
                    // Done counting down entries.
                } // Has new records or any entries. 
                else
                {
                    // if condition failed, we either have no records in the eventlog or we have no entries that are more recent than our last start time.
                    Finish(ref eventLog,
                        CheckId,
                        String.Format("Resetting current number of consecutive health check failures and exiting. The eventlog has no valid entries to check.  Last failure count was '{0}'.",
                        CurrentConsecutiveFailures.ToString()));

                    LastTotalLogEntries = currentTotalLogEntries;

                    CurrentConsecutiveFailures = 0;

                    LastTotalLogEntries = currentTotalLogEntries;

                    return;
                }
            }
            catch (Exception ex)
            {
                string message = string.Format("Exception caught while opening and parsing the event log: '{0}', '{1}'.",
                    ex.Message,
                    ex.InnerException.Message);

                Publish(ErrorCheckId,
                                message,
                                true,
                                DefinedEventLogName,
                                LastTotalLogEntries,
                                DefinedSource,
                                CheckId,
                                DefinedEntryType,
                                CurrentConsecutiveFailures,
                                DefinedMaxLogEntries,
                                DefinedMaxSecondsToRead);

                if (eventLog != default(EventLog))
                {
                    Finish(ref eventLog, CheckId, message);
                }
                else
                {
                    Finish(CheckId, message);
                }

                CurrentConsecutiveFailures = 0;

                return;
            }

            Finish(CheckId, "Exiting Eventlog Health Check.");
        }

        /// <summary>
        /// Check to see if the eventlog has any entries greater than the last start time.
        /// </summary>
        /// <param name="mostRecentWriteTime">The write time of the eventlog entry with the most recent write time.</param>
        /// <param name="lastPullStartTime">The start time of our last check.</param>
        /// <param name="eventLogEntriesCount">The total number of entries in the eventlog.</param>
        /// <returns>True if the write time of the most recent record is greater than the last start time and if the total number of eventlog
        /// entries is greater than the total number of our last check.</returns>
        private bool HasNewEntries(string checkId, DateTime mostRecentWriteTime, DateTime lastPullStartTime, int eventLogEntriesCount, int lastTotalLogEntries)
        {
            if (DateTime.Compare(mostRecentWriteTime, lastPullStartTime) > 0)
            {
                Logger.Debug("'{0}': New entries since last check. Most recent entry '{1}' > time of last pull '{2}'",
                    checkId,
                    mostRecentWriteTime.ToString(),
                    lastPullStartTime.ToString());
                return true;
            }

            if (DateTime.Compare(mostRecentWriteTime, lastPullStartTime) == 0)
            {
                Logger.Debug("'{0}': Entries times are equal to our last check. Most recent entry '{1}' == time of last pull '{2}'",
                    checkId,
                    mostRecentWriteTime.ToString(),
                    lastPullStartTime.ToString());

                if (eventLogEntriesCount > lastTotalLogEntries)
                {
                    Logger.Debug("'{0}': Total entries are more than our last pull. Last total '{1}', current total '{2}'.",
                        checkId,
                        lastTotalLogEntries,
                        eventLogEntriesCount);

                    return true;
                }
                else
                {
                    Logger.Debug("'{0}': Entries are less than or equal to than our last pull. Last total '{1}', current total '{2}'.",
                        checkId,
                        lastTotalLogEntries,
                        eventLogEntriesCount);

                    return false;
                }
            }

            Logger.Debug("'{0}': All entries in the event log are older than our last check time.", checkId);
            return false;
        }

        /// <summary>
        /// Determines if the Eventlog has any records at all.
        /// </summary>
        /// <param name="totalEventLogEntries">The total number of entries in the eventlog.</param>
        /// <returns>True if the eventlog has any records.</returns>
        private bool HasRecords(string checkid, int totalEventLogEntries)
        {
            if (totalEventLogEntries < 1)
            {
                Logger.Debug("'{0}': There are no records in the event log.", checkid);
                return false;
            }

            Logger.Debug("'{0}': There are records in the eventlog.", checkid);
            return true;
        }

        /// <summary>
        /// See if the last Start Time is older than our max number of seconds.
        /// </summary>
        /// <param name="LastStartTime">The time from the working file of our last start time.</param>
        /// <returns>True if the write time of the eventlog entry is under the number defined in the config file.</returns>
        private bool IsUnderMaxSeconds(string checkId, string errorCheckId, DateTime lastStartTime, int definedMaxSecondsToRead)
        {
            if (DateTime.Compare(lastStartTime, DateTime.Now.AddSeconds(-definedMaxSecondsToRead)) < 0)
            {
                String messagePart = string.Format("'{0}': Over limit for maximum number of seconds to check. (Last StartTime = '{1}' - Max Seconds = '{2}'). Publishing error.",
                checkId,
                lastStartTime.ToString(),
                definedMaxSecondsToRead.ToString());

                return false;
            }

            Logger.Debug("'{0}': Within time limits for max number of seconds to check. Defined Max Seconds =  '{1}'. Last StartTime = '{2}'. ",
                checkId,
                definedMaxSecondsToRead.ToString(),
                lastStartTime.ToString());

            return true;
        }

        /// <summary>
        /// Writes the current time to a file with in the working directory. 
        /// The time is written with every start. However, it is only used when Wolfpack starts.
        /// During execution we use the value in memory.
        /// </summary>
        /// <param name="currentSearchPullStartTime">The time we started looking for events.</param>
        private bool SetStartTime(string checkId, FileInfo filename, DateTime startTime)
        {
            try
            {
                DirectoryInfo di = new DirectoryInfo(filename.DirectoryName);

                if (!di.Exists)
                {
                    di.Create();
                }

                using (StreamWriter sw = new StreamWriter(filename.ToString(), false))
                {
                    sw.WriteLine(startTime.ToString());
                    sw.Flush();
                    sw.Close();
                    sw.Dispose();
                }

                Logger.Debug("'{0}': Start time set at: '{1}'.",
                    checkId,
                    startTime);
                return true;
            }
            catch (Exception ex)
            {
                string message = string.Format("'{0}': Exception while writing start time: '{1}'.",
                    checkId,
                    ex.InnerException.Message);
                Logger.Debug(message);
                return false;
            }
        }

        /// <summary>
        /// Checks to see if the current number of health check failures is >= the configured value.
        /// </summary>
        /// <param name="CurrentFailures">The current number of health check failures.</param>
        /// <returns>True if the current number of health check failures is greater than or equal to the number in the config file.</returns>
        private bool IsEqualToOrOverNumberOfConsecutiveFailures(string checkId, int currentFailures, int definedFailures)
        {
            if (currentFailures >= definedFailures)
            {
                Logger.Debug("'{0}': Current failures '{1}' is >= defined check failures '{2}'.",
                    checkId,
                    currentFailures.ToString(),
                    definedFailures.ToString());
                return true;
            }

            Logger.Debug("'{0}': Current failures '{1}' is <= defined check failures '{2}'.",
                checkId,
                currentFailures.ToString(),
                definedFailures.ToString());
            return false;
        }

        /// <summary>
        /// Check to see if the number of event matches is greater than or equal to the configured setting.
        /// </summary>
        /// <param name="numberOfMatches">The current number of event matches.</param>
        /// <returns></returns>
        private bool IsEqualToOrOverNumberOfEventLogMatches(string checkId, int numberOfMatches, int definedNumberOfMatches)
        {
            if (numberOfMatches >= definedNumberOfMatches)
            {
                Logger.Debug("'{0}': Match on eventlog entry consecutive matches '{1}'.",
                    checkId,
                    numberOfMatches.ToString());
                return true;
            }

            Logger.Debug("'{0}': No match on eventlog entry consecutive matches '{1}'.",
                checkId,
                numberOfMatches.ToString());
            return false;
        }

        /// <summary>
        /// Checks to see if the eventlog entry is greater than our last start time.
        /// </summary>
        /// <param name="entryWriteTime">The write time of the event log entry.</param>
        /// <param name="lastPullStartTime">The last start time of the eventlog plugin.</param>
        /// <returns>True if the write time of the event log entry is greater than the last start time.</returns>
        private bool IsGreaterThanLastStartTime(string checkId, DateTime entryWriteTime, DateTime lastPullStartTime)
        {
            // Check only log entries that have a DateTime > the last start time.
            if (DateTime.Compare(entryWriteTime, lastPullStartTime) >= 0)
            {
                Logger.Debug("'{0}': Eventlog entry is more recent or equal to than last check. Time Written: '{1}', Last Check Start Time '{2}'.",
                    checkId,
                    entryWriteTime.ToString(),
                    lastPullStartTime);

                return true;
            }

            Logger.Debug("'{0}': Eventlog entry is not more recent or equal to than last check. Time Written: '{1}', Last Check Start Time '{2}'.",
                checkId,
                entryWriteTime.ToString(),
                lastPullStartTime);
            return false;
        }

        /// <summary>
        /// Checks the current number of log entries that we have parsed through the setting in the config file.
        /// </summary>
        /// <param name="currentLogNumberIteration">The number of entries we have parsed through.</param>
        /// <returns>True if the current number of eventlog entries we have parsed through is less than the setting in the config file.</returns>
        private bool IsUnderMaxLogEntries(string checkId, int currentLogNumberIteration)
        {
            if (currentLogNumberIteration > DefinedMaxLogEntries)
            {
                Logger.Debug("'{0}': We have exceeded the maximum number of entries to check. Current number we are checking: '{1}'.",
                    checkId,
                    currentLogNumberIteration.ToString());

                return false;
            }

            Logger.Debug("'{0}': We have not exceeded the maximum number of entries to check. Current number we are checking: '{1}'.",
                checkId,
                currentLogNumberIteration.ToString());

            return true;
        }

        /// <summary>
        /// Closes out the eventlog and writes a message to the log.
        /// </summary>
        /// <param name="eventLog">The eventlog to close.</param>
        /// <param name="messagePart">The message to write to the log.</param>
        private void Finish(ref EventLog eventLog, string checkId, string messagePart)
        {
            try
            {
                eventLog.Close();
                eventLog.Dispose();
            }
            catch (Exception e)
            {
                Logger.Debug("'{0}': Unable to close out the eventlog. '{1}'",
                    checkId,
                    e.Message);
            }

            Finish(checkId, messagePart);
        }

        /// <summary>
        /// Writes a message to the log.
        /// </summary>
        /// <param name="message">The message to write.</param>
        private void Finish(string checkId, string messagePart)
        {
            Logger.Debug("'{0}': Done searching event log at: '{1}'.  Message: '{2}'",
            checkId,
            DateTime.Now.ToString(),
            messagePart);
        }

        /// <summary>
        /// Publishes a healthcheck to the publisher defined in the config file.
        /// </summary>
        /// <param name="checkId">The name of the HealthCheck</param>
        /// <param name="messagePart">The message to publish.</param>
        /// <param name="isError">Determines if a 0 or null should be sent as the result.</param>

        private void Publish(
            string checkId,
            string messagePart,
            bool? isError,
            string definedEventLogName,
            int lastTotalLogEntries,
            string definedSource,
            string friendlyId,
            string definedEntryType,
            int currentConsecutiveFailures,
            int definedMaxLogEntries,
            int definedMaxSecondsToRead)
        {
            Logger.Debug("'{0}': Publishing.  Error state is '{1}'. Current Consecutive Errors is '{2}'.",
                checkId,
                isError.ToString(),
                CurrentConsecutiveFailures.ToString());

            identity.Name = checkId;

            if (isError == true)
            {
                isError = null;
            }


            Messenger.Publish(
                new HealthCheckData
                {
                    Identity = identity,
                    Result = isError,
                    ResultCount = currentConsecutiveFailures,
                    Info = String.Format("'{0}': Error information about the Eventlog", friendlyId),
                    Properties = new ResultProperties
                        {
                            { "Message", messagePart },
                            { "Log name", definedEventLogName },
                            { "Total Log Entries parsed", lastTotalLogEntries.ToString()},
                            { "Source", definedSource },
                            { "FriendlyId", friendlyId},
                            { "Type", definedEntryType },
                            { "Number of failures", currentConsecutiveFailures.ToString() },
                            { "Threshold value for number of records.", definedMaxLogEntries.ToString() },
                            { "Threshold value for number of seconds to check.", definedMaxSecondsToRead.ToString() }
                        }
                });
        }

        private bool IsMatchOnMessage(string checkId, string message, string searchExpression)
        {
            if (message.Contains(searchExpression.ToLower()))
            {
                Logger.Debug("'{0}': Match on search expression. '{1}'",
                    checkId,
                    searchExpression);
                return true;
            }

            return false;
        }

        private bool IsMatchOnSource(string checkId, string source)
        {
            if (String.Compare(source, DefinedSource, true) == 0)
            {
                Logger.Debug("'{0}': Match on Source. '{1}' = '{2}'",
                    checkId,
                    source,
                    DefinedSource);
                return true;
            }

            return false;
        }

        private bool IsMatchOnType(string checkId, string type)
        {
            if (String.Compare(type, DefinedEntryType, true) == 0)
            {
                Logger.Debug("'{0}': Match on Type. '{1}' = '{2}'",
                    checkId,
                    type,
                    DefinedEntryType);
                return true;
            }

            return false;
        }
    }
}